package com.gadgets.cm05.statistic;

import com.gadgets.cm05.common.dto.MathList;
import com.gadgets.cm05.common.dto.MathMap;
import com.gadgets.framework.common.exception.GadgetsValidateException;
import com.gadgets.framework.common.util.MathBasicUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.math3.stat.StatUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;

/**
 * 功能说明：平均值工具类
 * 著作者：修峻青
 * 创建日期：2023-01-07
 */
public class AvgUtils {

    /**
     * 算数平均
     * @param itemList  样本
     * @param scale     数据精度
     * @return          算术平均值
     */
    public static BigDecimal mean(MathList<BigDecimal> itemList, int scale){
        if(CollectionUtils.isEmpty(itemList)){
            throw new GadgetsValidateException("样本不能为空");
        }
        double[] doubles = MathBasicUtil.translateListToDoubleArray(itemList, scale);
        return new BigDecimal(StatUtils.mean(doubles)).setScale(scale, RoundingMode.HALF_UP);
    }

    /**
     * 算数平均
     * 默认小数点后6位精度
     * @param itemList  样本
     * @return          算术平均值
     */
    public static BigDecimal mean(MathList<BigDecimal> itemList){
        return mean(itemList, 6);
    }

    /**
     * 几何平均
     * @param itemList  样本
     * @param scale     数据精度
     * @return          几何平均值
     */
    public static BigDecimal geometricMean(MathList<BigDecimal> itemList, int scale){
        if(CollectionUtils.isEmpty(itemList)){
            throw new GadgetsValidateException("样本不能为空");
        }
        double[] doubles = MathBasicUtil.translateListToDoubleArray(itemList, scale);
        return new BigDecimal(StatUtils.geometricMean(doubles)).setScale(scale, RoundingMode.HALF_UP);
    }

    /**
     * 几何平均
     * 默认小数点后6位精度
     * @param itemList  样本
     * @return          几何平均值
     */
    public static BigDecimal geometricMean(MathList<BigDecimal> itemList){
        return geometricMean(itemList, 6);
    }

    /**
     * 加权平均
     * @param itemMap   数据集合
     * @param scale     数据精度
     * @return          加权平均数
     */
    public static BigDecimal productMean(MathMap<BigDecimal, BigDecimal> itemMap, int scale){
        if(null==itemMap || itemMap.size()<1){
            throw new GadgetsValidateException("样本不能为空");
        }
        BigDecimal totalNum = BigDecimal.ZERO;
        BigDecimal totalSum = BigDecimal.ZERO;
        for (Map.Entry<BigDecimal, BigDecimal> entry : itemMap.entrySet()) {
            // 总数累加
            totalNum = totalNum.add(entry.getKey()).setScale(scale, RoundingMode.HALF_UP);
            // 总和累加
            totalSum = totalSum.add(entry.getKey().multiply(entry.getValue())).setScale(scale, RoundingMode.HALF_UP);
        }
        return totalSum.divide(totalNum);
    }

    /**
     * 加权平均
     * 默认小数点后6位精度
     * @param itemMap   数据集合
     * @return          加权平均数
     */
    public static BigDecimal productMean(MathMap<BigDecimal, BigDecimal> itemMap){
        return productMean(itemMap, 6);
    }

}
